﻿using System;
using System.Collections.Generic;
using System.Reflection;
using MiniJSON;

namespace DeJson
{
	// Token: 0x02000043 RID: 67
	public class Deserializer
	{
		// Token: 0x06000219 RID: 537 RVA: 0x000114AC File Offset: 0x0000F6AC
		public Deserializer()
		{
			this.m_creators = new Dictionary<Type, Deserializer.CustomCreator>();
		}

		// Token: 0x0600021A RID: 538 RVA: 0x000114C4 File Offset: 0x0000F6C4
		public T Deserialize<T>(string json)
		{
			object o = Json.Deserialize(json);
			return this.Deserialize<T>(o);
		}

		// Token: 0x0600021B RID: 539 RVA: 0x000114E4 File Offset: 0x0000F6E4
		public T Deserialize<T>(object o)
		{
			return (T)((object)this.ConvertToType(o, typeof(T), null));
		}

		// Token: 0x0600021C RID: 540 RVA: 0x00011510 File Offset: 0x0000F710
		public void RegisterCreator(Deserializer.CustomCreator creator)
		{
			Type key = creator.TypeToCreate();
			this.m_creators[key] = creator;
		}

		// Token: 0x0600021D RID: 541 RVA: 0x00011534 File Offset: 0x0000F734
		private object DeserializeO(Type destType, Dictionary<string, object> src, Dictionary<string, object> parentSrc)
		{
			object obj = null;
			bool flag = destType == typeof(Dictionary<string, object>);
			object result;
			if (flag)
			{
				result = src;
			}
			else
			{
				Deserializer.CustomCreator customCreator;
				bool flag2 = this.m_creators.TryGetValue(destType, out customCreator);
				if (flag2)
				{
					obj = customCreator.Create(src, parentSrc);
				}
				bool flag3 = obj == null;
				if (flag3)
				{
					object obj2;
					bool flag4 = src.TryGetValue("$dotNetType", out obj2);
					if (flag4)
					{
						destType = Type.GetType((string)obj2);
					}
					obj = Activator.CreateInstance(destType);
				}
				this.DeserializeIt(obj, src);
				result = obj;
			}
			return result;
		}

		// Token: 0x0600021E RID: 542 RVA: 0x000115C0 File Offset: 0x0000F7C0
		private void DeserializeIt(object dest, Dictionary<string, object> src)
		{
			Type type = dest.GetType();
			FieldInfo[] fields = type.GetFields();
			this.DeserializeClassFields(dest, fields, src);
		}

		// Token: 0x0600021F RID: 543 RVA: 0x000115E8 File Offset: 0x0000F7E8
		private void DeserializeClassFields(object dest, FieldInfo[] fields, Dictionary<string, object> src)
		{
			foreach (FieldInfo fieldInfo in fields)
			{
				bool isStatic = fieldInfo.IsStatic;
				if (!isStatic)
				{
					object value;
					bool flag = src.TryGetValue(fieldInfo.Name, out value);
					if (flag)
					{
						this.DeserializeField(dest, fieldInfo, value, src);
					}
				}
			}
		}

		// Token: 0x06000220 RID: 544 RVA: 0x00011640 File Offset: 0x0000F840
		private void DeserializeField(object dest, FieldInfo info, object value, Dictionary<string, object> src)
		{
			Type fieldType = info.FieldType;
			object obj = this.ConvertToType(value, fieldType, src);
			bool flag = fieldType.IsAssignableFrom(obj.GetType());
			if (flag)
			{
				info.SetValue(dest, obj);
			}
		}

		// Token: 0x06000221 RID: 545 RVA: 0x0001167C File Offset: 0x0000F87C
		private object ConvertToType(object value, Type type, Dictionary<string, object> src)
		{
			bool isArray = type.IsArray;
			object result;
			if (isArray)
			{
				result = this.ConvertToArray(value, type, src);
			}
			else
			{
				bool isGenericType = type.IsGenericType;
				if (isGenericType)
				{
					result = this.ConvertToList(value, type, src);
				}
				else
				{
					bool flag = type == typeof(string);
					if (flag)
					{
						result = Convert.ToString(value);
					}
					else
					{
						bool flag2 = type == typeof(byte);
						if (flag2)
						{
							result = Convert.ToByte(value);
						}
						else
						{
							bool flag3 = type == typeof(sbyte);
							if (flag3)
							{
								result = Convert.ToSByte(value);
							}
							else
							{
								bool flag4 = type == typeof(short);
								if (flag4)
								{
									result = Convert.ToInt16(value);
								}
								else
								{
									bool flag5 = type == typeof(ushort);
									if (flag5)
									{
										result = Convert.ToUInt16(value);
									}
									else
									{
										bool flag6 = type == typeof(int);
										if (flag6)
										{
											result = Convert.ToInt32(value);
										}
										else
										{
											bool flag7 = type == typeof(uint);
											if (flag7)
											{
												result = Convert.ToUInt32(value);
											}
											else
											{
												bool flag8 = type == typeof(long);
												if (flag8)
												{
													result = Convert.ToInt64(value);
												}
												else
												{
													bool flag9 = type == typeof(ulong);
													if (flag9)
													{
														result = Convert.ToUInt64(value);
													}
													else
													{
														bool flag10 = type == typeof(char);
														if (flag10)
														{
															result = Convert.ToChar(value);
														}
														else
														{
															bool flag11 = type == typeof(double);
															if (flag11)
															{
																result = Convert.ToDouble(value);
															}
															else
															{
																bool flag12 = type == typeof(float);
																if (flag12)
																{
																	result = Convert.ToSingle(value);
																}
																else
																{
																	bool flag13 = type == typeof(int);
																	if (flag13)
																	{
																		result = Convert.ToInt32(value);
																	}
																	else
																	{
																		bool flag14 = type == typeof(float);
																		if (flag14)
																		{
																			result = Convert.ToSingle(value);
																		}
																		else
																		{
																			bool flag15 = type == typeof(double);
																			if (flag15)
																			{
																				result = Convert.ToDouble(value);
																			}
																			else
																			{
																				bool flag16 = type == typeof(bool);
																				if (flag16)
																				{
																					result = Convert.ToBoolean(value);
																				}
																				else
																				{
																					bool flag17 = type == typeof(bool);
																					if (flag17)
																					{
																						result = Convert.ToBoolean(value);
																					}
																					else
																					{
																						bool isValueType = type.IsValueType;
																						if (isValueType)
																						{
																							result = this.DeserializeO(type, (Dictionary<string, object>)value, src);
																						}
																						else
																						{
																							bool isClass = type.IsClass;
																							if (isClass)
																							{
																								result = this.DeserializeO(type, (Dictionary<string, object>)value, src);
																							}
																							else
																							{
																								result = value;
																							}
																						}
																					}
																				}
																			}
																		}
																	}
																}
															}
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
			return result;
		}

		// Token: 0x06000222 RID: 546 RVA: 0x0001196C File Offset: 0x0000FB6C
		private object ConvertToArray(object value, Type type, Dictionary<string, object> src)
		{
			List<object> list = (List<object>)value;
			int count = list.Count;
			Type elementType = type.GetElementType();
			Array array = Array.CreateInstance(elementType, count);
			int num = 0;
			foreach (object value2 in list)
			{
				object value3 = this.ConvertToType(value2, elementType, src);
				array.SetValue(value3, num);
				num++;
			}
			return array;
		}

		// Token: 0x06000223 RID: 547 RVA: 0x00011A00 File Offset: 0x0000FC00
		private object ConvertToList(object value, Type type, Dictionary<string, object> src)
		{
			object obj = Activator.CreateInstance(type);
			MethodInfo method = type.GetMethod("Add");
			List<object> list = (List<object>)value;
			Type returnType = type.GetMethod("Find").ReturnType;
			foreach (object value2 in list)
			{
				object obj2 = this.ConvertToType(value2, returnType, src);
				method.Invoke(obj, new object[]
				{
					obj2
				});
			}
			return obj;
		}

		// Token: 0x04000208 RID: 520
		private Dictionary<Type, Deserializer.CustomCreator> m_creators;

		// Token: 0x02000299 RID: 665
		public abstract class CustomCreator
		{
			// Token: 0x06000DEE RID: 3566
			public abstract object Create(Dictionary<string, object> src, Dictionary<string, object> parentSrc);

			// Token: 0x06000DEF RID: 3567
			public abstract Type TypeToCreate();
		}
	}
}
